home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / xlib / toverlay.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  12KB  |  484 lines

  1. /*
  2.  * (c) Copyright 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. /*
  39. ** % cc -o toverlay toverlay.c -lGL
  40. */
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <GL/gl.h>
  45. #include <GL/glx.h>
  46. #include <X11/Xlib.h>
  47. #include <X11/keysym.h>
  48.  
  49. #define DISPLAY_BOTH        0
  50. #define DISPLAY_NORMAL        1
  51. #define DISPLAY_OVERLAY        2
  52.  
  53. static void
  54. drawSquare(float c)
  55. {
  56.     glIndexf(c);
  57.  
  58.     glBegin(GL_QUADS);
  59.     glVertex3f(0.0, 0.0, 0.0);
  60.     glVertex3f(1.0, 0.0, 0.0);
  61.     glVertex3f(1.0, 1.0, 0.0);
  62.     glVertex3f(0.0, 1.0, 0.0);
  63.     glEnd();
  64. }
  65.  
  66. static void
  67. drawCheck(float c1, float c2)
  68. {
  69.     int w = 4, h = 4;
  70.     int i, j;
  71.  
  72.     for (j=0; j<h; ++j) {
  73.     for (i=0; i<w; ++i) {
  74.         glPushMatrix();
  75.         glTranslatef((1.0/w) * i, (1.0/h) * j, 0.0);
  76.         glScalef(1.0/w, 1.0/h, 1.0);
  77.         if ((i & 1) ^ (j & 1)) {
  78.         drawSquare(c1);
  79.         } else {
  80.         drawSquare(c2);
  81.         }
  82.         glPopMatrix();
  83.     }
  84.     }
  85. }
  86.  
  87. static void
  88. usage(int argc, char **argv)
  89. {
  90.     fprintf(stderr, "\n");
  91.     fprintf(stderr, "usage: %s [options]\n", argv[0]);
  92.     fprintf(stderr, "\n");
  93.     fprintf(stderr, "    OpenGL overlay plane rendering test\n");
  94.     fprintf(stderr, "\n");
  95.     fprintf(stderr, "  Options:\n");
  96.     fprintf(stderr, "    -nm       just display normal plane window\n");
  97.     fprintf(stderr, "    -ov       just display overlay plane window\n");
  98.     fprintf(stderr, "    -m mode   display both windows according to mode:\n");
  99.     fprintf(stderr, "               0  overlay is child of normal (default)\n");
  100.     fprintf(stderr, "               1  both are children of root\n");
  101.     fprintf(stderr, "               2  both are children of a child of root\n");
  102.     fprintf(stderr, "    -bindov   bind opengl to overlay window first\n");
  103.     fprintf(stderr, "    -gl       toggle opengl rendering\n");
  104.     fprintf(stderr, "    -a        toggle animation\n");
  105.     fprintf(stderr, "\n");
  106. }
  107.  
  108. static Colormap
  109. buildColormap(Display *dpy, Window win, XVisualInfo *xvis)
  110. {
  111.     Colormap cmap;
  112.  
  113.     if ((cmap = XCreateColormap(dpy, win, xvis->visual, AllocNone)) == None) {
  114.     fprintf(stderr, "can't create colormap\n");
  115.     exit(EXIT_FAILURE);
  116.     }
  117.  
  118.     if (xvis->class == PseudoColor) {
  119.     int mapSize = 1 << xvis->depth;
  120.     int firstEntry = 0;
  121.     int entry;
  122.     unsigned long *pixels;
  123.  
  124.     pixels = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
  125.  
  126.     if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize))
  127.     {
  128.         if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize-1))
  129.         {
  130.         fprintf(stderr, "can't alloc enough colormap entries\n");
  131.         exit(EXIT_FAILURE);
  132.         }
  133.         firstEntry = 1;
  134.     }
  135.  
  136.     for (entry=firstEntry; entry<mapSize; ++entry) {
  137.         XColor xcol;
  138.         int hue = entry % 8;
  139.         short val = 0xffff;
  140.  
  141.         xcol.pixel = entry;
  142.         xcol.red   = (hue==1 || hue==5 || hue==6 || hue==7) ? val : 0;
  143.         xcol.green = (hue==2 || hue==4 || hue==6 || hue==7) ? val : 0;
  144.         xcol.blue  = (hue==3 || hue==4 || hue==5 || hue==7) ? val : 0;
  145.         xcol.flags = DoRed | DoGreen | DoBlue;
  146.  
  147.         XStoreColor(dpy, cmap, &xcol);
  148.     }
  149.  
  150.     free((void *) pixels);
  151.     }
  152.  
  153.     return cmap;
  154. }
  155.  
  156. static void
  157. windopen(Display **dpy_ret, Window *win_ret,
  158.      GLXContext *ctx_ret, int *visAttrs,
  159.      const char *name, int w, int h)
  160. {
  161.     static Display *dpy = NULL;
  162.     int scr;
  163.     Window root;
  164.     XVisualInfo *xvis;
  165.     GLXContext ctx;
  166.     XSetWindowAttributes xswa;
  167.     Colormap cmap;
  168.     Window win;
  169.     XEvent event;
  170.  
  171.     if (dpy == NULL) {
  172.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  173.         fprintf(stderr, "can't open display\n");
  174.         exit(EXIT_FAILURE);
  175.     }
  176.     }
  177.     scr = DefaultScreen(dpy);
  178.     root = RootWindow(dpy, scr);
  179.  
  180.     if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
  181.     fprintf(stderr, "can't find visual\n");
  182.     exit(EXIT_FAILURE);
  183.     }
  184.  
  185.     if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
  186.     fprintf(stderr, "can't create context\n");
  187.     exit(EXIT_FAILURE);
  188.     }
  189.  
  190.     xswa.colormap = buildColormap(dpy, root, xvis);
  191.     xswa.background_pixel = 0;
  192.     xswa.border_pixel = 0;
  193.     xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
  194.     win = XCreateWindow(dpy, root, 0, 0, w, h, 0,
  195.             xvis->depth, InputOutput, xvis->visual,
  196.             CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
  197.             &xswa);
  198.     
  199.     if (name) {
  200.     XStoreName(dpy, win, name);
  201.     }
  202.     
  203.     *dpy_ret = dpy;
  204.     *win_ret = win;
  205.     *ctx_ret = ctx;
  206. }
  207.  
  208. static Bool
  209. waitForNotify(Display *dpy, XEvent *event, XPointer arg)
  210. {
  211.     return (event->type == MapNotify && event->xmap.window == (Window) arg);
  212. }
  213.  
  214. static int normalVisAttrs[] = {
  215.     GLX_LEVEL, 0,
  216.     GLX_BUFFER_SIZE, 4,
  217.     None
  218. };
  219.  
  220. static int overlayVisAttrs[] = {
  221.     GLX_LEVEL, 1,
  222.     GLX_BUFFER_SIZE, 2,
  223.     None
  224. };
  225.  
  226. int
  227. main(int argc, char **argv)
  228. {
  229.     int mode = DISPLAY_BOTH;
  230.     int useGL = 1;
  231.     int animate = 1;
  232.     int manageTogether = 1;
  233.     int manageUsingParent = 0;
  234.     int delayBind = 0;
  235.     int width = 300, height = 300;
  236.     int ovWidth = width, ovHeight = height;
  237.     float spin0 = 0.0, spinRate0 = 1.0;
  238.     float spin1 = 45.0, spinRate1 = -1.0;
  239.     int normInit = 0;
  240.     int overInit = 0;
  241.     Display *dpy;
  242.     Window parentWin = None;
  243.     GLXContext parentCtx = None;
  244.     Window normWin = None;
  245.     GLXContext normCtx = None;
  246.     Window overWin = None;
  247.     GLXContext overCtx = None;
  248.     XEvent event;
  249.     int i;
  250.  
  251.     for (i=1; i<argc; ++i) {
  252.     if (!strcmp("-nm", argv[i]))
  253.     {
  254.         mode = DISPLAY_NORMAL;
  255.     }
  256.     else if (!strcmp("-ov", argv[i]))
  257.     {
  258.         mode = DISPLAY_OVERLAY;
  259.     }
  260.     else if (!strcmp("-m", argv[i]) && (i+1 < argc))
  261.     {
  262.         mode = DISPLAY_BOTH;
  263.         switch (atoi(argv[++i])) {
  264.           case 0:
  265.         manageTogether = 1; manageUsingParent = 0;
  266.         break;
  267.           case 1:
  268.         manageTogether = 0; manageUsingParent = 0;
  269.         break;
  270.           case 2:
  271.         manageTogether = 1; manageUsingParent = 1;
  272.         break;
  273.           default:
  274.         usage(argc, argv);
  275.         exit(EXIT_FAILURE);
  276.         break;
  277.         }
  278.     }
  279.     else if (!strcmp("-bindov", argv[i]))
  280.     {
  281.         delayBind = 1;
  282.     }
  283.     else if (!strcmp("-gl", argv[i]))
  284.     {
  285.         useGL = !useGL;
  286.     }
  287.     else if (!strcmp("-a", argv[i]))
  288.     {
  289.         animate = !animate;
  290.     }
  291.     else
  292.     {
  293.         usage(argc, argv);
  294.         exit(EXIT_FAILURE);
  295.     }
  296.     }
  297.  
  298.     if (mode == DISPLAY_BOTH && manageUsingParent) {
  299.     windopen(&dpy, &parentWin, &parentCtx,
  300.          normalVisAttrs, "overlay test", width, height);
  301.  
  302.     XMapWindow(dpy, parentWin);
  303.     XIfEvent(dpy, &event, waitForNotify, (XPointer) parentWin);
  304.     }
  305.  
  306.     if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
  307.     windopen(&dpy, &normWin, &normCtx,
  308.          normalVisAttrs, "overlay test", width, height);
  309.  
  310.     if (mode == DISPLAY_BOTH && manageUsingParent) {
  311.         XReparentWindow(dpy, normWin, parentWin, 0, 0);
  312.     }
  313.  
  314.     XMapWindow(dpy, normWin);
  315.     XIfEvent(dpy, &event, waitForNotify, (XPointer) normWin);
  316.  
  317.     if (useGL && !delayBind) {
  318.         glXMakeCurrent(dpy, normWin, normCtx);
  319.     }
  320.     }
  321.  
  322.     if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
  323.     windopen(&dpy, &overWin, &overCtx,
  324.          overlayVisAttrs, "overlay test", ovWidth, ovHeight);
  325.     
  326.     if (mode == DISPLAY_BOTH && manageTogether) {
  327.         if (manageUsingParent) {
  328.         XReparentWindow(dpy, overWin, parentWin, 0, 0);
  329.         } else {
  330.         XReparentWindow(dpy, overWin, normWin, 0, 0);
  331.         }
  332.     }
  333.  
  334.     XMapWindow(dpy, overWin);
  335.     XIfEvent(dpy, &event, waitForNotify, (XPointer) overWin);
  336.  
  337.     if (useGL && !delayBind) {
  338.         glXMakeCurrent(dpy, overWin, overCtx);
  339.     }
  340.     }
  341.  
  342.     if (mode == DISPLAY_BOTH && manageTogether) {
  343.     Window winList[3];
  344.  
  345.     if (manageUsingParent) {
  346.         winList[0] = overWin;
  347.         winList[1] = normWin;
  348.         winList[2] = parentWin;
  349.         XSetWMColormapWindows(dpy, parentWin, winList, 3);
  350.     } else {
  351.         winList[0] = overWin;
  352.         winList[1] = normWin;
  353.         XSetWMColormapWindows(dpy, normWin, winList, 2);
  354.     }
  355.     }
  356.  
  357.     while (1) {
  358.     int reconfigure = 0;
  359.     int redraw = 0;
  360.  
  361.     if (XPending(dpy)) {
  362.         KeySym ks;
  363.  
  364.         XNextEvent(dpy, &event);
  365.         switch (event.type) {
  366.           case KeyPress:
  367.         XLookupString(&event.xkey, NULL, 0, &ks, NULL);
  368.         if (ks == XK_Escape) {
  369.             exit(EXIT_SUCCESS);
  370.         }
  371.         break;
  372.           case Expose:
  373.         redraw = 1;
  374.         break;
  375.           case ConfigureNotify:
  376.         if (mode == DISPLAY_BOTH && manageTogether) {
  377.             if (manageUsingParent &&
  378.             event.xconfigure.window == parentWin)
  379.             {
  380.             width = ovWidth = event.xconfigure.width;
  381.             height = ovHeight = event.xconfigure.height;
  382.             XResizeWindow(dpy, normWin, width, height);
  383.             XResizeWindow(dpy, overWin, ovWidth, ovHeight);
  384.             }
  385.             if (!manageUsingParent &&
  386.             event.xconfigure.window == normWin)
  387.             {
  388.             width = ovWidth = event.xconfigure.width;
  389.             height = ovHeight = event.xconfigure.height;
  390.             XResizeWindow(dpy, overWin, ovWidth, ovHeight);
  391.             }
  392.         } else {
  393.             if (event.xconfigure.window == normWin) {
  394.             width = event.xconfigure.width;
  395.             height = event.xconfigure.height;
  396.             }
  397.             if (event.xconfigure.window == overWin) {
  398.             ovWidth = event.xconfigure.width;
  399.             ovHeight = event.xconfigure.height;
  400.             }
  401.         }
  402.         reconfigure = 1;
  403.         redraw = 1;
  404.         break;
  405.           default:
  406.         break;
  407.         }
  408.     }
  409.  
  410.     if (animate) {
  411.         spin0 += spinRate0;
  412.         if (spin0 > 360.0) spin0 -= 360.0;
  413.  
  414.         spin1 += spinRate1;
  415.         if (spin1 > 360.0) spin1 -= 360.0;
  416.  
  417.         redraw = 1;
  418.     }
  419.  
  420.     if (useGL) {
  421.         if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
  422.         if (mode == DISPLAY_BOTH || !overInit) {
  423.             glXMakeCurrent(dpy, overWin, overCtx);
  424.  
  425.             if (!overInit) {
  426.             glMatrixMode(GL_PROJECTION);
  427.             glOrtho(-1, 1, -1, 1, 1, 3);
  428.             glMatrixMode(GL_MODELVIEW);
  429.             glTranslatef(0.0, 0.0, -2.0);
  430.             glLineWidth(4.0);
  431.             overInit = 1;
  432.             }
  433.         }
  434.  
  435.         if (reconfigure) {
  436.             glViewport(0, 0, ovWidth, ovHeight);
  437.         }
  438.  
  439.         if (redraw) {
  440.             glClear(GL_COLOR_BUFFER_BIT);
  441.  
  442.             glPushMatrix();
  443.             glRotatef(spin1, 0, 0, 1);
  444.             glScalef(1.25, 1.25, 1.0);
  445.             glTranslatef(-0.5, -0.5, 0.0);
  446.             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  447.             drawCheck(1, 2);
  448.             glPopMatrix();
  449.         }
  450.         }
  451.  
  452.         if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
  453.         if (mode == DISPLAY_BOTH || !normInit) {
  454.             glXMakeCurrent(dpy, normWin, normCtx);
  455.  
  456.             if (!normInit) {
  457.             glMatrixMode(GL_PROJECTION);
  458.             glOrtho(-1, 1, -1, 1, 1, 3);
  459.             glMatrixMode(GL_MODELVIEW);
  460.             glTranslatef(0.0, 0.0, -2.0);
  461.             normInit = 1;
  462.             }
  463.         }
  464.  
  465.         if (reconfigure) {
  466.             glViewport(0, 0, width, height);
  467.         }
  468.  
  469.         if (redraw) {
  470.             glClear(GL_COLOR_BUFFER_BIT);
  471.  
  472.             glPushMatrix();
  473.             glRotatef(spin0, 0, 0, 1);
  474.             glScalef(1.25, 1.25, 1.0);
  475.             glTranslatef(-0.5, -0.5, 0.0);
  476.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  477.             drawCheck(3, 4);
  478.             glPopMatrix();
  479.         }
  480.         }
  481.     }
  482.     }
  483. }
  484.